﻿using FlowDesigner.Flow;
using FlowDesigner.HelperVision;
using FlowDesigner.INotifyCommadBase;
using FlowDesigner.Loadinganimation;
using FlowDesigner.Models;
using FlowDesigner.View;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using Unity;
using static System.Windows.Forms.LinkLabel;

namespace FlowDesigner.ViewModel
{
    public class MainViewModel
    {
        public List<ContextMenuFile> ContextMenuFileList {  get; set; }
        public List<FloWTask> ProcessNodeList { get; set; }
        public Dictionary<string, string> iconfontlist { get; set; }

        private Canvas canvas_;
        //连接线颜色
        public SolidColorBrush solidColorBrush;
        //鼠标移动连接线颜色
        public SolidColorBrush solidColorBrush1;
        /// <summary>
        /// 删除
        /// </summary>
        public ParameterCommand<NodeS> Deletecommand {  get; set; }
        /// <summary>
        /// 编辑
        /// </summary>
        public ParameterCommand<NodeS> Editcommand {  get; set; }
        /// <summary>
        /// 保存流程节点
        /// </summary>
        public ParameterCommand<Canvas> Savenodecommand {  get; set; }
        /// <summary>
        /// 打开保存的流程节点
        /// </summary>
        public ParameterCommand<Canvas> openFileecommand {  get; set; }
        /// <summary>
        /// 清空所有节点
        /// </summary>
        public ParameterCommand<Canvas> DeleteAllcommand { get; set; }
        /// <summary>
        /// 测试流程
        /// </summary>
        public ParameterCommand<Canvas> Testnodecommand { get; set; }
        public MainViewModel()
        {
            ContextMenuFileList= new List<ContextMenuFile>();
            iconfontlist = new Dictionary<string, string>();
            ProcessNodeList= new List<FloWTask>();
            iconfontlist.Add("起始", "\ue63c");
            iconfontlist.Add("流程", "\xe600");
            iconfontlist.Add("结束", "\ue6ec");
            iconfontlist.Add("链接", "\uead2");

            solidColorBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#409EFF"));
            solidColorBrush1 = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#A6A9AD"));
            //命令实例化
            Deletecommand =new ParameterCommand<NodeS>(Deletecommand_);
            Editcommand= new ParameterCommand<NodeS>(Editcommand_);
            Savenodecommand = new ParameterCommand<Canvas>(Savenodecommand_);
            openFileecommand = new ParameterCommand<Canvas>(openFileecommand_);
            DeleteAllcommand = new ParameterCommand<Canvas>(DeleteAllcommand_);
            Testnodecommand = new ParameterCommand<Canvas>(Testnodecommand_);
        }
        private void Testnodecommand_(Canvas canvas)
        {
                BaseDialogViewModel mainViewModel = Containerfot.Container.container.Resolve<BaseDialogViewModel>();
                mainViewModel.Show(typeof(TestprocessView), typeof(TestprocessViewModel), o =>
                {
                    var datalist=o as List<object>;
                    foreach (UIElement item in datalist)
                    {
                        canvas.Children.Add(item);
                    }
                },
                canvas
                );
            
        }

        private void DeleteAllcommand_(Canvas canvas)
        {
            canvas.Children.Clear();
            ProcessNodeList.Clear();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        private void Savenodecommand_(Canvas obj)
        {
                string path = GetFilePath(1);
                // 显示对话框并判断用户是否选择了文件夹
                if (string.IsNullOrEmpty(path)==false)
                {
                    if(XMLserialization.Savexaml(XMLserialization.NodsUItoXml(obj.Children,obj), path))
                    {
                        System.Windows.Forms.MessageBox.Show("保存成功");
                    }
                }
                else
                {
                    System.Windows.Forms.MessageBox.Show("请选择文件夹");
                }
            
          
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        private void openFileecommand_(Canvas obj)
        {
            //LoadingBase mainViewModel = Containerfot.Container.container.Resolve<LoadingBase>();
            //前面给提示
            string path = GetFilePath(2);
            // 显示对话框并判断用户是否选择了文件夹
            if (string.IsNullOrEmpty(path) == false)
            {
                ProcessNodeList.Clear();
                obj.Children.Clear();

                //mainViewModel.IsopenLoading = true;
                    // 创建一个内存中的 Canvas 容器

                    ProcessNodeList = XMLserialization.Deserializationxaml<FloWTask>(path);
                    foreach (var item in ProcessNodeList)
                    {
                            NodeS nodeS = new NodeS();
                            nodeS.Description = item.Description;
                            nodeS.Width = 100;
                            nodeS.Height = 100;
                            nodeS.Tag = item.Tag;
                            nodeS.strFont = iconfontlist[item.Tag];
                            nodeS.Foreground = string.Equals(item.Tag, "结束") ? new SolidColorBrush(Colors.Red) : new SolidColorBrush(Color.FromArgb(255, 0, 150, 242));
                            nodeS.ParentItemsControl = item;
                            Canvas.SetLeft(nodeS, item.NodeSX); // 水平位置
                            Canvas.SetTop(nodeS, item.NodeSY);  // 垂直位置
                            obj.Children.Add(nodeS);
                            if (item.X1 != 0 && item.Y1 != 0)
                            {
                                Line lindata = DrawBezierCurve(item.X, item.Y, item.X1, item.Y1);
                                //添加鼠标移动事件
                                lindata.MouseEnter += Line_MouseEnter;
                                lindata.MouseLeave += Line_MouseLeave;
                                lindata.MouseDown += Line_MouseDown;
                                obj.Children.Add(lindata);
                                DrawArrow(new Point()
                                {
                                    X = item.X,
                                    Y = item.Y,
                                },
                                 new Point()
                                 {
                                     X = item.X1,
                                     Y = item.Y1,
                                 });
                                var d = DrawArrow(new Point()
                                {
                                    X = item.X,
                                    Y = item.Y,
                                },
                                new Point()
                                {
                                    X = item.X1,
                                    Y = item.Y1,
                                });
                                obj.Children.Add(d[0]);
                                obj.Children.Add(d[1]);
                            }
                            ContextMenu contextMenu = new ContextMenu();
                            contextMenu.SetResourceReference(MenuItem.StyleProperty, "ContextMenusty"); // 从资源中应用样式;
                            nodeS.ContextMenu = contextMenu;
                            // 添加 MenuItem
                            MenuItem menuItem1 = new MenuItem { Header = "删除" };
                            menuItem1.SetBinding(MenuItem.CommandProperty, new System.Windows.Data.Binding("Deletecommand"));// 绑定命令
                            menuItem1.CommandParameter = nodeS;
                            MenuItem menuItem2 = new MenuItem { Header = "编辑" };
                            menuItem2.SetBinding(MenuItem.CommandProperty, new System.Windows.Data.Binding("Editcommand"));// 绑定命令
                            menuItem2.CommandParameter = nodeS;
                            contextMenu.Items.Add(menuItem1);
                            contextMenu.Items.Add(menuItem2);
                    }
     
               // mainViewModel.IsopenLoading = false;
                canvas_ = obj;
            }
            else
            {
                System.Windows.Forms.MessageBox.Show("请选择文件");
            }
        }
        // 鼠标进入时改变颜色
        private void Line_MouseEnter(object sender, MouseEventArgs e)
        {
            e.Handled = true;
            (sender as Line).Stroke =solidColorBrush1;
        }

        // 鼠标离开时还原颜色
        private void Line_MouseLeave(object sender, MouseEventArgs e)
        {
            e.Handled = true;
            (sender as Line).Stroke = solidColorBrush;
        }
        Line line1 = null;
        // 鼠标按下时显示上下文菜单
        private void Line_MouseDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
            line1 = sender as Line;

            ContextMenu contextMenu = new ContextMenu();
            contextMenu.SetResourceReference(MenuItem.StyleProperty, "ContextMenusty");

            // 添加菜单项
            MenuItem menuItem1 = new MenuItem { Header = "删除" };
            menuItem1.Click += MenuItem1_Click;

            contextMenu.Items.Add(menuItem1);
            line1.ContextMenu = contextMenu;
            //打开上下文菜单
            contextMenu.IsOpen = true;
        }

        private void MenuItem1_Click(object sender, RoutedEventArgs e)
        {
            var listui = VisuaXml.GetElementAllLineornodes(canvas_, line1.X2, line1.Y2);
            foreach (var item in listui)
            {
                if (item is Line)
                {
                    canvas_.Children.Remove(item as Line);
                }
            }
            canvas_.Children.Remove(line1);
            var NodeSlist_ = VisuaXml.GetElementAt<NodeS>(canvas_, line1.X1, line1.Y1);//起始节点
            if (NodeSlist_ == null)
            {
                System.Windows.Forms.MessageBox.Show("删除链接失败!");//
            }
            if (NodeSlist_.ParentItemsControl.Branch)
            {
                var NodeSlistend = VisuaXml.GetElementAt<NodeS>(canvas_, line1.X2, line1.Y2);//起始节点
                if (NodeSlistend == null)
                {
                    System.Windows.Forms.MessageBox.Show("删除链接失败!");//
                }
                NodeSlist_.ParentItemsControl.NexflowIndexBranch.Remove(NodeSlistend.ParentItemsControl.flowIndex);
            }
            else
            {
                NodeSlist_.ParentItemsControl.NexflowIndex = 0;//清除链接
            }
            line1.MouseEnter += Line_MouseEnter;
            line1.MouseLeave += Line_MouseLeave;
            line1.MouseDown += Line_MouseDown;
        }
        /// <summary>
        /// 获取文件路径 1 文件夹 2 文件路径
        /// </summary>
        /// <returns></returns>
        private string GetFilePath(int pathtype)
        {
            if (pathtype == 1)
            {
                using (System.Windows.Forms.FolderBrowserDialog dialog = new System.Windows.Forms.FolderBrowserDialog())
                {
                    dialog.Description = "请选择文件夹";  // 设置对话框描述
                    dialog.RootFolder = Environment.SpecialFolder.MyComputer;  // 设置根目录
                    dialog.ShowNewFolderButton = true;  // 允许用户创建新文件夹

                    // 显示对话框并判断用户是否选择了文件夹
                    if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        return dialog.SelectedPath;

                    }
                    else
                    {
                        return null;
                    }
                }
            }
            if (pathtype == 2)
            {
              System.Windows.Forms.OpenFileDialog dialog = new System.Windows.Forms.OpenFileDialog();     
                if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                  return dialog.FileName;
                }
                dialog.Dispose();
            }
            return null;
        }
        /// <summary>
        /// 流程节点编辑
        /// </summary>
        /// <param name="s"></param>
        private void Editcommand_(NodeS s)
        {
            //    // 获取 MainViewModel 实例
            BaseDialogViewModel mainViewModel = Containerfot.Container.container.Resolve<BaseDialogViewModel>();
            mainViewModel.ShowDialog(typeof(EditflownodeView), typeof(EditflownodeViewModel), o =>
            {
                var data = o as flownodeEditModel;
                s.ParentItemsControl.Description = data.Description;
                s.Description = data.Description;
                s.ParentItemsControl.Executionconditions = data.Executionconditions;
                if (data.branch)
                {
                    s.ParentItemsControl.Branch = data.branch;
                    s.ParentItemsControl.NexflowIndexBranch.Add(s.ParentItemsControl.flowIndex);
                    s.ParentItemsControl.NexflowIndex = -1;
                }
            },
            s.ParentItemsControl          
            );
        }
        private void Deletecommand_(NodeS s)
        {
            if (s.ParentItemsControl.Tag=="起始"&& ProcessNodeList.Any(o=>o.NexflowIndex==s.ParentItemsControl.flowIndex))
            {
                System.Windows.Forms.MessageBox.Show("起始节点已经链接!"); // 鼠标点击事件
                return;
            }
            if (s.ParentItemsControl.NexflowIndex != 0)
            {
                System.Windows.Forms.MessageBox.Show("已经链接节点不能清除,必须先删除链接!"); // 鼠标点击事件
                return;
            }
            if (s.ParentItemsControl.Branch&& ProcessNodeList.Any(o => !o.NexflowIndexBranch.Contains(s.ParentItemsControl.flowIndex)))
            {

                System.Windows.Forms.MessageBox.Show("已经链接节点不能清除,必须先删除链接!"); // 鼠标点击事件
                return;
            }
            var cavas_=   VisuaXml.FindVisualParent<Canvas>(s);
            if (cavas_ != null)
            {
                ProcessNodeList.Remove(s.ParentItemsControl);
                cavas_.Children.Remove(s);
                //移出所有事件
                s.MouseMove -= s.NodeS_MouseMove;
                s.MouseLeftButtonDown -= s.NodeS_MouseLeftButtonDown;
                s.MouseLeftButtonUp -= s.NodeS_MouseLeftButtonUp;
                s.MouseLeave -= s.NodeS_MouseLeave;
                s.Dispose();
            }
        }

        // 绘制直线
        private Line DrawBezierCurve(double X1,double Y1,double X2, double Y2)
        {
            Line line_ = new Line();
            line_.Stroke = solidColorBrush;
            line_.StrokeThickness = 2;
            line_.X1 =X1;
            line_.Y1 = Y1;
            line_.X2 = X2;
            line_.Y2 = Y2;
            return line_ ;
        }
        /// <summary>
        /// 绘制带箭头的直线
        /// </summary>
        /// <param name="canvas">绘制的 Canvas</param>
        /// <param name="start">直线的起点</param>
        /// <param name="end">直线的终点</param>
        /// <param name="arrowLength">箭头的长度</param>
        /// <param name="arrowAngle">箭头与直线的夹角（单位：度）</param>
        public List<Line> DrawArrow(Point start, Point end, double arrowLength = 20, double arrowAngle = 30)
        {
            Line arrowLine1=new Line();
            Line arrowLine2=new Line();
            arrowLine1.Stroke = solidColorBrush;
            arrowLine1.StrokeThickness = 2;

            arrowLine2.Stroke = solidColorBrush;
            arrowLine2.StrokeThickness = 2;
            // 计算直线的角度（弧度）
            double angle = Math.Atan2(end.Y - start.Y, end.X - start.X);
            // 算出箭头的两条线段的角度
            double angle1 = angle + arrowAngle * Math.PI / 180; // 顺时针方向
            double angle2 = angle - arrowAngle * Math.PI / 180; // 逆时针方向
            // 算出箭头两端点
            Point arrowPoint1 = new Point(
                end.X - arrowLength * Math.Cos(angle1),
                end.Y - arrowLength * Math.Sin(angle1)
            );
            Point arrowPoint2 = new Point(
                end.X - arrowLength * Math.Cos(angle2),
                end.Y - arrowLength * Math.Sin(angle2)
            );
            arrowLine1.X1 = end.X;
            arrowLine1.Y1 = end.Y;
            arrowLine1.Y2 = arrowPoint1.Y;
            arrowLine1.X2 = arrowPoint1.X;
            arrowLine2.X1 = end.X;
            arrowLine2.Y1 = end.Y;
            arrowLine2.X2 = arrowPoint2.X;
            arrowLine2.Y2 = arrowPoint2.Y;
            return new List<Line> { arrowLine1, arrowLine2 };
        }
    }
}
